<script>

var Yesss = {
  loginURL: 'https://www.yesss.at/kontomanager.php',
  overviewURL: 'https://www.yesss.at/kontomanager/uebersicht.php?PHPSESSID=',
  logoutURL: 'https://www.yesss.at/kontomanager.php?dologout=1&PHPSESSID=',
  PHPSESSID: '',
  pollTimeout: 0,
  pollTimerId: -1,
  timeout: 30000,
  phoneNumber: '',
  password: '',
  toTimerId: -1,
  waitTimer: -1,
  init: function() {
    this.update('...');
    this.phoneNumber = localStorage.phoneNumber;
    console.log('phoneNumber: ' + this.phoneNumber);
    this.password = localStorage.password;
    this.pollTimeout = localStorage.pollTimeout;
    console.log('pollTimeout: ' + this.pollTimeout);
    this.login();
  },
  setCredentials: function(phoneNumber, password) {
    console.log('Modified credentials: ' + phoneNumber);
    this.phoneNumber = phoneNumber;
    this.password = password;
    if (this.toTimerId != -1) {
      console.log('wait for the previous request');
      if (this.waitTimer == -1) {
        /* wait until the request finishes */
        this.waitTimer = window.setInterval(function(){
            /* request finished */
            if (Yesss.toTimerId == -1) {
              console.log('previous request finished');
              window.clearTimeout(Yesss.waitTimer);
              Yesss.waitTimer = -1;
              Yesss.login();
            }
          }, 500
        );
      }
    } else {
      this.login(); 
    }
  },
  login: function() {
    if (!this.phoneNumber || !this.password) {
      console.log('Phone number or password not set');
      this.update('E-LO');
      if (this.PHPSESSID != '') {
        this.logout();
      }
      return;
    }
    console.log('Login...');
    this.update('...');
    this.ajax({
      method: "POST",
      url: this.loginURL,
      data: 'login_rufnummer='+this.phoneNumber+'&login_passwort='+this.password,
      success: function() {
        if (this.status == '200' && this.responseText) {
          Yesss.PHPSESSID = Yesss.parseSession(this.responseText);
          if (Yesss.PHPSESSID != '') {
            console.log('PHPSESSID: ' + Yesss.PHPSESSID);
            Yesss.update(Yesss.parseBalance(this.responseText));
          } else {
            console.log('Login failed');
            Yesss.update('E-LO');
          }
        } else {
          console.log('Wrong response');
          Yesss.update('E-NW');
        }
      },
      error: function() {
        console.error('Error loading URL');
        Yesss.update('E-NW');
      },
      timeout: function() {
        console.error('Timeout login request');
        Yesss.update('E-TO');
      }
    });
  },
  updateBalance: function() {
    if (this.PHPSESSID != '') {
      console.log('Overview...');
      this.ajax({
        method: "GET",
        url: this.overviewURL + this.PHPSESSID,
        success: function(){
          if (this.status == '200' && this.responseText) {
            console.log('Updated');
            if (Yesss.parseSession(this.responseText) == Yesss.PHPSESSID) {
              Yesss.update(Yesss.parseBalance(this.responseText));
            } else {
              console.log('Session timeout');
              Yesss.PHPSESSID = '';
              Yesss.login();
            }
          } else {
            console.log('Wrong response');
            Yesss.update('E-NW');
          }
        },
        error: function() {
          console.error('Error loading URL');
          Yesss.update('E-NW');
        },
        timeout: function() {
          console.error('Timeout login request');
          Yesss.update('E-TO');
        }
      });
    }
  },
  logout: function() {
    if (this.PHPSESSID != '') {
      console.log('Logout...');
      this.ajax({
        method: "GET",
        url: this.logoutURL + this.PHPSESSID,
        success: function(){
          if (this.status == '200' && this.responseText) {
            Yesss.PHPSESSID = '';
            console.log('Logged out');
            Yesss.update('E-LO');
          } else {
            console.log('Wrong response');
            Yesss.update('E-NW');
          }
        },
        error: function(err) {
          console.error('Error loading URL');
          Yesss.update('E-NW');
        },
        timeout: function() {
          console.error('Timeout logout request');
          Yesss.update('E-TO');
        }
      });
    }
  },
  parseSession: function(source) {
    var match = source.match(/<a href='\/kontomanager\.php\?dologout=1\&PHPSESSID=(\w+)'/);
    if (match) {
      return match[1];
    } else {
      return '';
    }
  },
  parseBalance: function(source) {
    // Diskont-Surfen Grundoption: 
    //   <td class='listcontent-info'><b>EUR 4,11 / ca. 210 MB</b></td> 
    // YESSS! 9 Cent: 
    //   <td class='listcontent-info'><b>EUR 0,04</b></td>
    var match = source.match(/<td class='listcontent-info'><b>EUR ([\d,]+).*?<\/b><\/td>/);
    var bal;
    if (match) {
      var balF = parseFloat(match[1].replace(',', '.'));
      if (balF >= 10) {
        balF = Math.round(balF * 10) / 10.0;
      }
      bal = balF.toString();
    } else {
      bal = 'E-BA';
    }
    return bal;
  },
  ajax: function(obj /* method, url, data, success, error, timeout */) {
    if (this.toTimerId != -1) {
      /* Connection in progress */
      console.log('request in progress');
      return;
    }
    var xhr = new XMLHttpRequest();
    try {
      console.log("request...");
      xhr.onload = function(e) {
        console.log("readystate: " + xhr.readyState);
        if (Yesss.toTimerId != -1) {
          window.clearTimeout(Yesss.toTimerId);
          Yesss.toTimerId = -1;
        }
        if (typeof(obj.success) == 'function') {
          obj.success.call(xhr);
        }
        Yesss.schedule();
      }
      xhr.onerror = function(e) {
        console.log('error: ' + e
          +', readyState: ' + xhr.readyState
          + ', statusCode: ' + xhr.status);
        if (Yesss.toTimerId != -1) {
          window.clearTimeout(Yesss.toTimerId);
          Yesss.toTimerId = -1;
        }
        if (typeof(obj.error) == 'function') {
          obj.error.call(xhr);
        }
        Yesss.schedule();
      }

      xhr.open(obj.method, obj.url, true);
      if (obj.method == 'POST' && typeof(obj.data) == 'string') {
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        //xhr.setRequestHeader("Content-length", obj.data.length);
        //xhr.setRequestHeader("Connection", "close");
        xhr.send(obj.data);
      } else {
        xhr.send(null);
      }

      // Give up after 5 seconds
      this.toTimerId = window.setTimeout(function() {
        console.log("Timeout...");
        xhr.abort();
        Yesss.toTimerId = -1;
        /* Try again later... */
        if (typeof(obj.timeout) == 'function') {
          obj.timeout.call();
        }
        Yesss.schedule();
      }, this.timeout);
    } catch(e) {
      console.log("ex: " + e);
      console.error("exception: " + e);
      if (typeof(obj.error) == 'function') {
        obj.error.call(xhr, e.message);
      }
    }
  },
  update: function (count) {
    if (typeof(count) == 'number') {
      count = count.toString();
    }
    chrome.browserAction.setBadgeText({ text: count });
    chrome.browserAction.setTitle({ title: "Yesss! - updated " + this.getFormattedDate() });
  },
  getFormattedDate: function() {
    var d = new Date();
    var d1 = [
      d.getFullYear(),
      d.getMonth(),
      d.getDate(),
      d.getHours(),
      d.getMinutes()
    ];
    d[1]++;
    if (d1[1] < 10) d1[1] = '0' + d1[1];
    if (d1[2] < 10) d1[2] = '0' + d1[2];
    if (d1[3] < 10) d1[3] = '0' + d1[3];
    if (d1[4] < 10) d1[4] = '0' + d1[4];
    return d1[0] + '-' + d1[1] + '-' + d1[2] + ' ' + d1[3] + ':' + d1[4];
  },
  schedule: function() {
    if (this.pollTimeout) {
      // if there is something scheduled, cancel it
      this.unschedule();
      var toCall = this.PHPSESSID != '' ? this.updateBalance : this.login;
      console.log('schedule ' + (this.PHPSESSID != '' ? 'updateBalance' : 'login') + ' for ' + this.pollTimeout);
      this.pollTimerId = window.setTimeout(function(thisObj, func) {
          Yesss.pollTimerId = -1;
          console.log('calling scheduled function');
          func.call(thisObj);
        }, this.pollTimeout, this, toCall
      );
    }
  },
  unschedule: function() {
    if (this.pollTimerId != -1) {
      console.log('polling unscheduled');
      window.clearTimeout(this.pollTimerId);
      this.pollTimerId = -1;
    }
  },
  setPollTimeout: function(timeout) {
    console.log('pollTimeout changed to ' + timeout);
    this.pollTimeout = timeout;
    if (this.toTimerId == -1 && this.pollTimerId != -1) {
      /* If there is a request in progres, the reschedule 
         happen right after its finish */
      console.log('rescheduling polling');
      this.unschedule();
      this.schedule();
    }
  }
};
Yesss.init();
</script>
